
/**
 *@Version 1.0.a 
 *
 * 1、Class 2、Model 3、View 4、Controller 5、Server Conn 6、Modules Load
 * TODO context path 
 */
var _name = 'FM';
(function($) {
	window.FM = {
		ns : function() {
			if(arguments.length<1){return;}
			var p = window,pkgs =arguments[0];
			if(arguments[1] != null){
				p  = arguments[0]; 
				pkgs =arguments[1];
			}
			if (!FM.isString(pkgs)) {return;}
			var arr = pkgs.split('.');
			for ( var i in arr) {
				if (!p[arr[i]]) {
					p[arr[i]] = {};
				}
				p[arr[i]]._parent = p;
				p[arr[i]]._name = arr[i];
				p = p[arr[i]];
			}
			return p;
		},
		each : function(arr, fn,filter) {
			if (!FM.isFunction(fn)) {return;}
			for ( var key in arr) {
				if(FM.isFunction(filter) && !filter(key,arr[key])){continue;}
				if(fn(key, arr[key]) === false ){break;}
			}
		},
		isFunction:function(fn){
			return typeof fn == 'function';
		},
		isString:function(str){
			return typeof str == 'string';
		},
		isObject:function(obj){
			return typeof obj == 'object';
		},		
		extend:function(){
			if (arguments.length == 0) {return;}
			if (FM.isString(arguments[0])) {
				if (!arguments[1]) {return;}

				var name = arguments[0];
				var pkg = this;
				if (name.indexOf('.') > 0) {
					pkg = FM.ns(this,name.substring(0,name.lastIndexOf('.')));
					name = name.substring(name.lastIndexOf('.') + 1);
				}
				pkg[name] = arguments[1];
			} else{
			    var self = this;
			    FM.each(arguments,function(i,arg){
			        for ( var key in arg) {
                        self[key] = arg[key];
                    }
			    },function(i,arg){
			        return FM.isObject(arg);
			    });
			}
		}
	};
	FM.extend('String',{
		upFirst : function(str) {
			if (str.length == 1) {return str.toUpperCase();}
			return str.charAt(0).toUpperCase() + str.substring(1);
		},
		isEmpty : function(str) {return !str || FM.trim(str).length == 0;},
		trim:function(str){
			if(FM.isEmpty(str)){return '';}
			return str.replaceAll(/^\s+|\s+^/,'');
		},
		endwith:function(str,sufix){
		    if(!FM.isString(str) || !FM.isString(sufix)){return false;}
		    return str.substring(str.length-sufix.length)==sufix;
		},
		startwith:function(str,pre){
			if(!FM.isString(str) || !FM.isString(pre)){return false;}
			return str.substr(0,str.length) == pre;
		},
		format:function(str,param){
			//TODO 
		}
	});
	FM.extend('import',function(){
	    	FM.each(arguments,function(i,arg){
	    		var script = document.createElement('script');
                script.src=arg;
                document.head.appendChild(script);
	    	},function(i,arg){
	    		return FM.String.endwith(arg,'.js');
	    	});
     });
	FM.extend('about',{
			author:'lion',
			email:'hl.0074@gmail.com',
			version:'0.1.a',
			date:'2013-03-11'
	});
	//extends
	FM.extend('OS',(function(){
			var name,version = '';
			if(navigator.platform.indexOf('Win')>-1){
				version = navigator.userAgent.match(/Windows NT ([\d\.]+)/i)[1];
				switch (version) {
				case '5.0':
					name= 'Windows 2000';break;
				case '5.1':
					name= 'Windows XP';break;
				case '5.2':
					name= 'Windows 2003';break;
				case '6.0':
					name= 'Windows Vista';break;
				case '6.1':
					name= 'Windows 7';break;
				case '6.2':
					name= 'Windows 8';break;
				default:
				name= 'Windows';break;
				}
			}else if(navigator.platform.indexOf('Mac')){
				name = 'Mac';
			}else if(navigator.platform.indexOf('Linux')){
				name ='Linux';
			}else if(navigator.platform.indexOf('X11')){
				name= 'Unix';
			}
			return {
				name:name,
				version:version,
				isWindows: name.toLowerCase().indexOf('windows')>=0
			};
	})());
	
	FM.extend('tmpl',function(str,obj){
		return str.replace(/\$\{(.*?)\}/g,function(w,$1){
			return obj[$1]||'';
		});
	});
	
	FM.extend('Browser',(function(){
			var agent = navigator.userAgent;
			var name,version,isie = false;
			if(agent.indexOf('MSIE')>-1){
				version = agent.match(/MSIE (\d+)/i)[1];
				name =  'Internet Explorer '+version;
				isie = true;
			}else if(agent.indexOf('Firefox')>-1){
				name= 'Firefox';
				version = agent.match(/Firefox\/([\d.]+)/i)[1];
			}else if(agent.indexOf('Opera')>-1){
				name= 'Opera';
				version = agent.match(/Opera ([\d.]+)/i)[1];
			}else if(agent.indexOf('Chrome')>-1){
				name= 'Chrome';
				version = agent.match(/Chrome\/([\d.]+)/i)[1];
			}else if(agent.indexOf('Safari')>-1){
				name= 'Safari';
				version = agent.match(/Safari\/([\d.]+)/i)[1];
			}
			return {
				name:name,
				version:version,
				isIE:isie
			};
	})());
	
	/**
	 * Class defination
	 */
	FM.extend('Class', function() {
		var name = arguments[0];
		if(!FM.isString(name)){ return;}
		
		var options = arguments[1] ||{};
		var staticMethods = arguments[2] || {};

		var klass = function() {
			if(FM.isFunction(options.parent)){
				options.parent.apply(this,[].slice.apply(arguments));
			}
			
			var self = this;
			//default properties
			FM.each(options,function(k,v){
				self[k] = v;
			},function(k,v){
				return !isNaN(v) || FM.isString(v) || typeof v == 'boolean';
			});
			//init
			if (options.init) {
				options.init.apply(this,[].slice.apply(arguments));
			}
		};

		//prototype
		klass.fn = klass.prototype = {
			constructor : klass
		};
		klass.fn.extend = klass.extend = FM.extend;
		
		// class instance method
		FM.each(options, function(k,v){
			klass.fn[k] = v;
		});
		
		//inherit function
		if(FM.isFunction(options.parent)){
			FM.each(options.parent.prototype, function(k,v){
				klass.fn[k] = v;
			}, function(k,v){
				return FM.isFunction(v) && !klass.fn[k];
			})
		}
		
		//class method
		FM.each(staticMethods,function(k,v){
			klass[k] = v;
		});
		
		// namespace
		var ns = window;
		var className = name;
		if (name.indexOf('.') > 0) {
			ns = FM.ns(name.substring(0, name.lastIndexOf('.')));
			className = name.substring(name.lastIndexOf('.') + 1);
		}
		ns[className] = klass;
		
		return klass;
	});
	
	/**
	 *	Collections 
	 */
	FM.Class('FM.Collection', {
		each:function(fn,filter){
			FM.each(this._collection, fn,filter);
		},
		isEmpty:function(){
			return this.size()==0;
		},
		contains:function(e){
          var b = false;
          this.each(function(i,v){
             if(e == v){b = true;return false;}
          });
          return b;
        }
	});
	
	FM.Class('FM.Map', {
	    parent:FM.Collection,
		init:function(){
			this._collection = {};
			this._size = 0;
		},
		put:function(key,value){
			if(!this._collection[key]){
				this._size++;
			}
			this._collection[key] = value;
		},
		get:function(key){
			return this._collection[key];
		},
		remove:function(key){
			if(this._collection[key]){
				this._size--;
			}
			delete this._collection[key];
		},
		size:function(){
			return this._size;
		},
		keys:function(){
			var arr = [];
			this.each(function(key,value){
				arr.push(key);
			});
			return arr;
		},
		values:function(){
			var arr = [];
			this.each(function(key,value){
				arr.push(value);
			});
			return arr;
		},
		clear:function(){
			this.init();
		}
	});
	
	FM.Class('FM.List', {
		parent:FM.Collection,
		init:function(){
			this._collection = [];
		},
		get:function(i){
			
			if(isNaN(i)){return null;}
			return this._collection[i];
		},
		add:function(o){
			this._collection.push(o);
		},
		set:function(i,v){
			
			if(isNaN(i)){return false;}
			this._collection.splice(i,1,v);
		},
		insert:function(i,v){
			
			if(isNaN(i)){return false;}
			this._collection.splice(i, 0,v);
		},
		remove:function(i){
			
			if(isNaN(i)){return false;}
			if(i<0){return false;}
			this._collection = this._collection.slice(0, i).concat(this._collection.slice(i+1));
		},
		removeValue:function(v){
		  return this.remove(this.index(v));
		},
		index:function(v){
			
			for ( var i = 0; i < this._collection.length; i++) {
				if(this._collection[i] == v){
					return i;
				}
			}
			return -1;
			
		},
		toArray:function(){
			return [].concat(this._collection);
		},
		clear:function(){
			this.init();
		},
		size:function(){
			return this._collection.length;
		}		
	});
	
	FM.Class('FM.Set',{
		parent:FM.List,
		init:function(){
			this._collection = [];
		},
		add:function(o){
			if(this.contains(o)){return false;}
			this._collection.push(o);
			return true;
		},
		set:function(i,v){
			if(isNaN(i)){return false;}
			if(this.contains(o)){return false;}
			this._collection.splice(i,1,v);
			return true;
		},
		insert:function(i,v){
			if(isNaN(i)){return false;}
			if(this.contains(o)){return false;}
			this._collection.splice(i, 0,v);
		}
	});
	
	
	//Utils
	FM.Class('FM.CountDown',{
		times:0,
		delay:1000,
		_interval:null,
		runtimes:0,
		init:function(times,intervals,fn,complete){
			this.times = times;
			this.delay = intervals;
			this._fn = fn;
			this._complete = complete;
		},
		start:function(){
			this.stop();
			var that = this;
			this._interval = setInterval(function(){
				if(that.runtimes++>=that.times){
					that.stop();
				}else{
					that.fn();
				}
			}, this.delay);
		},
		stop:function(){
			if(this._interval){
				clearInterval(this._interval);
			}
			this.runtimes = 0;
			this._complete();
		}
	});
	
	//MVC
	FM.Class('FM.Observable', {
		init:function(){
			this.events = new FM.Map();
		},
		bind:function(type,fn){
			
			if(!FM.isFunction(fn)){return;}
			
			var list = this.events.get(type);
			if(!list){
				list = new FM.List();
				this.events.put(type,list);
			}
			
			list.add(fn);
		},
		unbind:function(type){
		    this.events.remove(type);
		},
		notify:function(type,args){
			var list = this.events.get(type);
			if(!list){
				return;
			}
			var _this = this;
			list.each(function(i,fn){
				fn.call(_this,args);
			});
		},
		haveEvent:function(type){
			var list = this.events.get(type);
			return list && !list.isEmpty();
		},
		proxy:function(fn){
		    var self = this;
		   return function(){
		       fn.apply(self,[].slice.apply(arguments));
		   }
		}
	});
	
	FM.Class('FM.Event',{
	   init:function(target){
            this.events = new FM.List();
            this.target = target;
       },
       add:function(fn){
            if(!this.events.contains(fn)){
            this.events.add(fn);}
       },
       remove:function(fn){
            this.events.remove(fn);
       },
       fire:function(args){
           var _this = this;
           this.events.each(function(i,fn){
             fn.call(_this.target,args);
           });
       }
	});
	
	//mvc
	FM.Class('FM.MVC.Model', {
		parent:FM.Observable
	});
	FM.Class('FM.MVC.View', {
		parent:FM.Observable
	});
	FM.Class('FM.MVC.Controller', {
		parent:FM.Observable
	});
	
	//
	FM.extend('Model',function(name,options){
		
		options = options ;
		options.parent = FM.Model;
		
		var klass = FM.Class(name,options);
		
		return klass;
	});
	FM.extend('View',function(name,options){
		
		options = options ||{};
		options.parent = FM.mvc.View;
		var klass = FM.Class(name,options);
		
		return klass;
	});
	FM.extend('Controller',function(name,options){
		
		options = options ||{};
		options.parent = FM.mvc.Controller;
		var klass = FM.Class(name,options);
		
		return klass;
	});
	
	//Server
	//服务器交互
	FM.extend('Server',{});
	
	//Forms
	//submit,validate,get,set
	
	FM.Class('FM.Form',{
		parent:FM.Observable,
		init:function(ele,values){},
		submit:function(){},
		get:function(){},
		set:function(){},
		validate:function(){},
		params:function(){}
	});
	
	FM.extend('Form',function(id){
		return new FM.Form(id);
	});
	
	//Validator
	FM.extend('Validator',{
		isEmail:function(){
			
		},
		
		
		
	});
	//Tooltip
	FM.Class('FM.Tooltip',{});
	//Cover
	FM.Class('FM.Cover',{});
	//window
	
	//table
	FM.Class('FM.Table',{});
	//tab
	FM.Class('FM.Tab',{});
	//scrollbar
	
	//Tree
	FM.Class('FM.Tree.Node',{
	});
	FM.Class('FM.Tree',{});
	
	/**
	 * FM.size
	 * 可以获取overflow隐藏的元素的实际大小
	 */
	FM.extend('size',function(ele){
		
		var $ele = $(ele);
		if($ele.css('overflow') =='hidden'){
			var _$el = $ele.clone().css({'overflow':'auto',width:'auto',height:'auto','display':'none'});
			_$el.appendTo(document.body);
			
			var size = {width:_$el.width(),height:_$el.height()};
			_$el.remove();
			
			return size;
			
		}else if($ele.css('overflow-x') == 'hidden'){
			
			var _$el = $ele.clone().css({'overflow':'auto',width:'auto','display':'none'});
			_$el.appendTo(document.body);
			
			var size = {width:_$el.width(),height:_$el.height()};
			_$el.remove();
			
			return size;
			
		}else if($ele.css('overflow-y') == 'hidden'){
			var _$el = $ele.clone().css({'overflow':'auto',height:'auto','display':'none'});
			_$el.appendTo(document.body);
			
			var size = {width:_$el.width(),height:_$el.height()};
			_$el.remove();
			
			return size;
		}else{
			return {width:$ele.width(),height:$ele.width()};
		}
	});
	
	/**
	 * FM.copy
	 * @param {String} txt
	 */
	FM.extend('copy',function(txt){
		if(window.clipboardData){
			clipboardData.setData('Text',txt)
		}else if(window.netscape){
			try {
				netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
			} catch (e) {
				alert("被浏览器拒绝！\n请在浏览器地址栏输入'about:config'并回车\n然后将 'signed.applets.codebase_principal_support'设置为'true'");
				return;
			}
			var clip = Components.classes['@mozilla.org/widget/clipboard;1'].createInstance(Components.interfaces.nsIClipboard);
			if(!clip){return false;}
			
			var trans = Components.classes['@mozilla.org/widget/transferable;1'].createInstance(Components.interfaces.nsITransferable);
			if(!trans){return false;}
			trans.addDataFlavor('text/unicode');
			
			var str = new Object();
			var len = new Object();
			var supportsString = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString);
			str.data = txt;
			trans.setTransferData('text/unicode',supportsString,txt.length*2);
			
			var clipid = Components.interfaces.nsIClipboard;
			if (!clip){return false;}

			clip.setData(trans,null,clipid.kGlobalClipboard);
		}
	});
	
	/**
	 * drag and drop
	 * @method FM.dragable 
	 * @param  {String|jQuery} ele
	 * @param  {Object} options 
	 * options.dragging  {Function}
	 * options.drop {Function}
	 * options.start {Function}
	 * options.opacity {Number}
	 * options.axis {String}
	 */
	FM.extend('dragable',function(ele,options){
		options = $.extend({},options);
		
		$(ele).each(function(){
			
			var $el = $(this),$this = $(this),
			$handle = !options.handler?$el:$(options.handler,$el),
			delta = {x:0,y:0},
			userselect = $(document.body).css('-moz-user-select'),
			webkit_userselect = $(document.body).css('-khtml-user-select'),
			dyopacity =  options.opacity||1;
			
			if($.isFunction(options.dragging)){
				$this.bind('dragging',options.dragging);
			}
			if($.isFunction(options.drop)){
				$this.bind('dragend',options.drop);
			}
			var region = options.region || {left:0,top:0};
			$this.css('position','absolute');
			$handle.css('cursor','move');
			if(FM.isString(options.region)){
				var _$e = $(options.region);
				var pos = _$e.position();
				region = {
						left:pos.left,
						top:pos.top,
						right:pos.left+_$e.width(),
						bottom:pos.top+_$e.height()	
				};
				if(_$e,$el.parents(options.region).length>0){
					region = {
						left:0,
						top:0,
						right:_$e.width(),
						bottom:_$e.height()	
					};
				}
			}
			
			var mousedown = function(evt){
				if(options.fake){
					$e = $('<div>');
					$($e).css({
						position:'absolute',
						opacity:0.7,
						backgroundColor:'#eee',
						width:$el.width(),
						height:$el.height(),
						left:$el.offset().left,
						top:$el.offset().top,
						border:'dashed 1px #888'
					});
					$(document.body).append($e);
					$el = $handle = $e;
					dyopacity= 0.7;
				}
				if($.isFunction(options.start)){
					$el.one('dragingstart',options.start);
				}
				
				var offset = $el.css('position') == 'absolute'?$el.position():$el.offset();
				delta = {
						x:offset.left-evt.pageX,
						y:offset.top-evt.pageY
				};
				$(document).bind({
					mousemove:mousemove,
					mouseup:mouseup
				});
			};
		
			var mousemove = function(e){
				var o =  {left:e.pageX+delta.x,top:e.pageY+delta.y};
				
				if($.isFunction(options.path)){
					o = options.path(e);
				}
				//判断范围
				if($.isNumeric(region.left) && o.left < region.left){
					o.left = region.left;
				}
				if($.isNumeric(region.top) && o.top < region.top){
					o.top =  region.top;
				}
				if($.isNumeric(region.bottom) && o.top+$el.height() > region.bottom){
					o.top = region.bottom-$el.height();
				}
				if($.isNumeric(region.right) && o.left+$el.width() > region.right){
					o.left = region.right-$el.width();
				}
				//判断方向
				if(options.axis == 'x'){
					 delete o.top;	
				}else if(options.axis == 'y'){
					 delete o.left;
				}
				
				$.extend(o,{
					opacity:dyopacity
				});
				$el.trigger('start');
				$el.css(o);
				window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
				$el.trigger('dragging',{left:o.left,top:o.top});
			};
			var mouseup = function(e){
				if(options.fake){
					$this.animate({top:$el.offset().top,left:$el.offset().left},300);
					$el.remove();
					$el =  $this;
				}
				$el.css('opacity',1);
				$(document).unbind({
					mousemove:mousemove,
					mouseup:mouseup,
					selectstart:FM.fail
				});
				$el.trigger('drop');
			};
			
			$handle.bind('mousedown',mousedown);
		});
	});
	
	/**
	 * @method FM.slider
	 * @param {Object} options
	 * options.bar {String}
	 * options.region {Object}
	 * options.change {Function}
	 * options.axis {String}
	 * 
	 */
	FM.Class('FM.Slider',{
		parent:FM.Observable,
		init:function(ele,options){
			this.region = options.bar || options.region;
			this.track = $(ele);
			this.value = options.value || 0;
			this.axis = options.axis;
			
			if(FM.isFunction(options.change)){
				this.attach('change',options.change);
			}
			
			options = $.extend({
				region:this.region,
				dragging:$.proxy(this.dragging,this)
			},options);
			
			FM.dragable(this.track,options);
			this.val(this.value);
		},
		val:function(value){
			if(!$.isNumeric(value)){
				return this.value;
			}

			if(value == this.value){return;}
			//set value
			if(this.axis == 'x'){
				var left = 0;
				if(FM.isString(this.region)){
					var $region = $(this.region);
					left = ($region.width() - this.track.width())*value/100;
				}else if(FM.isObject(this.region)){
					var total = (this.region.right - this.region.left - this.track.width());
					left = total*value/100+this.region.left;
				}
				this.track.css('left',left.toFixed(0));
			}else if(this.axis == 'y'){
				var top = 0;
				if(FM.isString(this.region)){
					var $region = $(this.region);
					top = ($region.height() - this.track.height())*value/100;
				}else if(FM.isObject(this.region)){
					var total = (this.region.bottom - this.region.top - this.track.height());
					top = total*value/100+this.region.left;
				}
				this.track.css('top',top.toFixed(0));
			}
			this.value = value;
			this.notify('change',value);
		},
		dragging:function(event,o){
			
			if(!this.haveEvent('change')){
				return;
			}
			var delta = 0;
			var total = 0;
			
			if(this.axis == 'x'){
				if(FM.isString(this.region)){
					total = $(this.region).width() - this.track.width();
					delta = o.left;
				}else if(FM.isObject(this.region)){
					total = this.region.right - this.region.left - this.track.width();
					delta = o.left - this.region.left;
				}
			}else if(this.axis == 'y'){
				if(FM.isString(this.region)){
					total = $(this.region).height()-this.track.height();
					delta = o.top;
				}else if(FM.isObject(this.region)){
					total = this.region.bottom - this.region.top - this.track.height();
					delta = o.top - region.top;
				}
			}
			var val = delta/total;
			this.value = (val*100).toFixed(0);
			
			this.notify('change',this.value);
		}
	});
	
	FM.extend('slider',function(track,options){
		return new FM.Slider(track,options);
	});
	
	/**
	 * alert 
	 */
	
	FM.extend('center',function(el,parent){
		parent = parent|| window;
		
		var $e = $(el),$p = $(parent);
		var left = ($p.width()-$e.width())/2;
		var top = $($p.height()-$e.height())/2;
		$e.offset({left:left,top:top});
	});
	
	FM.Class('FM.Alert',{
		init:function(options){
			var me = this;
			this.options = $.extend({
				buttons:[{
					text:'确定',
					click:function(){
						me.close();
					}
				}],
				type:'default',
				parent:window
			},options);
			
			this.$box = $(FM.Alert.template);
			if(!this.options.title){
				$('.head',this.$box).remove();
			}else{
				$('.title',this.$box).html(this.options.title);
				FM.dragable(this.$box,{handler:'.head'});
			}
			$('.content',this.$box).html(this.options.content);
			
			var ftable = $('.foot table tr',this.$box);
			$(this.options.buttons).each(function(i,button){
				var $button = $('<td><span class="button">'+button.text+'</span></td>');
				ftable.append($button);
				
				if(button.click){
					$button.click($.proxy(button.click,me));
				}else{
					$button.click($.proxy(me.close,me));
				}
			});
			if(this.options.modal){
				this.cover = new FM.Cover();
			}
			this.$box.hide();
			$('.content',this.$box).css('border-color',FM.Alert.color[this.options.type]);
			$(document.body).append(this.$box);
			FM.center(this.$box);
		},
		show:function(){
			if (this.options.modal) {
				this.cover.show();
			}
			this.$box.show();
		},
		hide:function(){
			if (this.options.modal) {
				this.$box.hide();
			}
			this.cover.hide();
		},
		close:function(){
			this.$box.remove();
			if (this.options.modal) {
				this.cover.close();
			}
		}
	},{
		template:'<div class="window">\
			<div class="head">\
				<span class="title"></span>\
			</div>\
			<div class="content"></div>\
			<div class="foot">\
				<table width="100%" height="100%" cellspacing="5"  style="table-layout: fixed;">\
					<tr align="center">\
					</tr>\
				</table>\
				</div>\
		</div>',
		color:{
			danger:'#DA4F49',
			success:'#5BB75B',
			info:'#49AFCD',
			waring:'#FAA732',
			'default':'#A2D1F9'
		},
		confirm:function(content,fn){
			var alert = new FM.Alert({
				content:content,
				type:'info',
				title:'来自Firefox的提示',
				modal:true,
				buttons:[{
					text:'确认',
					click:fn
				},{
					text:'取消',
				}]
			});
			alert.show();
		},
		alert:function(content,type,fn){
			var alert = new FM.Alert({
				content:content,
				type:type||'default',
				modal:true,
				buttons:[{
					text:'确认',
					click:fn
				}]
			});
			alert.show();
		},
		success:function(content,fn){
			FM.Alert.alert(content,'success',fn);
		},
		warning:function(content,fn){
			FM.Alert.alert(content,'waring',fn);
		},
		info:function(content,fn){
			FM.Alert.alert(content,'info',fn);
		},
		error:function(content,fn){
			FM.Alert.alert(content,'error',fn);
		}
	});
	
	FM.Class('FM.Cover',{
		
		init:function(parent){
			parent = parent || window;
			this.$e = $('<div class="cover"></div>');
			this.$e.css({
				height:$(parent).height(),
				opacity:0.5
			});
			$(document.body).append(this.$e);
		},
		show:function(){
			this.$e.show();
		},
		hide:function(){
			this.$e.hide();
		},
		close:function(){
			this.$e.remove();
		}
	});
})(jQuery);
